package 二叉排序树;

import java.util.Objects;

/*
* 效率:
*  二叉排序树的查找速度类似于二分查找
* 条件:
*  要求左子节点的值比当前节点的值小
*  要求右子节点的值比当前节点的值大
* */
public class binarySortTreeDemo {
    public static void main(String[] args) {
        binarySortTree binarySortTree = new binarySortTree();
        int[] arr = {7,3,10,12,5,1,9,2};
        for (int i = 0; i < arr.length; i++) {
            Node node = new Node(arr[i]);
            binarySortTree.addNode(node);
        }
        binarySortTree.infixOrder();
        System.out.println("------------------------");
        binarySortTree.deleteNode(7);
        binarySortTree.infixOrder();
    }
}

// 创建二叉排序树
class binarySortTree{
    Node root;

    public binarySortTree(){

    }

    /**
     * 得到最小的节点
     * @param node 将node当做根节点
     * @return 返回以node为根节点的最小节点的值
     */
    public int getMinNode(Node node){
        if(node.left == null){
            return node.value;
        }
        return getMinNode(node.left);

    }

    // 删除节点
    public void deleteNode(int value){
        if(root == null){
            return;
        }else {
            Node search = search(value);
            if(search == null){
                return;
            }
            // 当前二叉树只有一个节点
            if(root.left == null && root.right == null){
                root = null;
                return;
            }

            Node parent = searchParent(value);
            if(search.left == null && search.right == null){// 删除叶子结点
                if(parent.left == search){
                    parent.left = null;
                }else{
                    parent.right = null;
                }
            } else if(search.left != null && search.right != null){// 删除有两颗子树的节点
                int minNode = getMinNode(search.right);
                Node node = search(minNode);
                deleteNode(minNode);
                search.value = minNode;
            }else{// 删除有一颗子树的节点
                if(parent.left == search){
                    if(search.left != null){
                        parent.left = search.left;
                    }else{
                        parent.left = search.right;
                    }
                }else{
                    if(search.left != null){
                        parent.right = search.left;
                    }else{
                        parent.right = search.right;
                    }
                }
            }
        }
    }

    // 查找当前节点
    public Node search(int value){
        if(root == null){
            return null;
        }else{
            return root.search(value);
        }
    }

    // 查找父节点
    public Node searchParent(int value){
        if(root == null){
            return null;
        }else{
            return root.searchParent(value);
        }
    }

    // 添加节点
    public void addNode(Node node){
        // 空树
        if(root == null){
            root = node;
        }else {
            root.addNode(node);
        }
    }

    // 中序遍历
    public void infixOrder(){
        if(root == null){
            System.out.println("二叉排序树为空树,无法遍历");
            return;
        }else{
            root.infixSort();
        }
    }

}

// 创建node节点
class Node{
    int value;
    Node left;
    Node right;

    /**
     * 查找节点
     * @param value 要查找节点的值
     * @return 找到了返回该节点,找不到返回空
     */
    public Node search(int value){
        if(value == this.value){
            return this;
        }else if(value < this.value){
            // 如果左子节点为空,直接返回空
            if(this.left == null){
                return null;
            }
            return this.left.search(value);
        }else{
            // 如果右子节点为空,直接返回空
            if(this.right == null){
                return null;
            }
            return this.right.search(value);
        }
    }


    /**
     * 查找要删除节点的父节点
     * @param value 要查找节点的值
     * @return 找到了返回this,找不到返回空
     */
    public Node searchParent(int value){
        if ((this.left != null && this.left.value == value)
                || (this.right != null && this.right.value == value)) {
            return this;
        }else{
            if(this.left != null && value < this.value){
                return this.left.searchParent(value);// 左子树递归
            }else if(this.right != null && value>= this.value){
                return this.right.searchParent(value);// 右子树递归
            }else{
                return null;// 没有找到父节点
            }
        }
    }

    // 添加节点的方法
    // 递归的形式添加节点,需要满足二叉排序树的要求
    public void addNode(Node node){
        if(node == null){
            return;
        }

        // 判断当前节点的值和传入节点的值的大小关系
        if(node.value > this.value){
            if(this.right != null) {
                // 向右递归添加
                this.right.addNode(node);
            }else{
                this.right = node;
            }
        }


        if(node.value < this.value){
            if(this.left != null) {
                // 向左递归添加
                this.left.addNode(node);
            }else{
                this.left = node;
            }
        }

    }

    // 中序遍历
    public void infixSort(){
        if(this.left != null){
            this.left.infixSort();
        }
        System.out.println(this.value);

        if(this.right != null){
            this.right.infixSort();
        }
    }

    public Node(int value){
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }
}
